package cmp.viewer.panels;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import util.ui.UserPrompt;

import cmp.main.Globals;
import cmp.viewer.ViewerFrame;
import cmp.viewer.controls.AssemblyCountPanel;
import cmp.viewer.controls.ButtonComboBox;
import cmp.viewer.controls.CollapsiblePanel;

public class POGQueryPanel extends JPanel {
	private static final long serialVersionUID = 1672776836742705318L;
	private static final String [] SECTIONS = { "Basic", "Cluster Info", "Species", "DE members"};
	private static final String [] SECTIONS_DESC = 	{ // display wrong as applet
														"", "", "", ""};
	public POGQueryPanel(ViewerFrame parentFrame) {
		theParentFrame = parentFrame;			
		createMainPanel();
		buildPanel(false);
	}
	
	private void clearFilters() {
		txtPOGID.setText("");
		txtBestHitID.setText("");
		txtBestHitDescrip.setText("");
		btnCmbMethod.setSelectedIndex(0);
		cmbTaxa.setSelectedIndex(0);
		theAssemCountPanel.setIncludeLimit("");
		theAssemCountPanel.setExcludeLimit("");
		theAssemCountPanel.setAllSelectedInc(false);
		theAssemCountPanel.setAllSelectedEx(false);
	
		theDEPanel.clearAll();
	}
	
	//Called by main frame to query the database
	public String getSubQuery() {
		String retVal = "";
		retVal = combineBool(retVal, getBasicQuery(), true);
		retVal = combineBool(retVal, getPOGInfoQuery(), true);
		retVal = combineBool(retVal, getSpeciesQuery(), true);
		retVal = combineBool(retVal, getDEQuery(), true);
		return retVal;
	}
	
	public String getQuerySummary() {
		String retVal = "";
		retVal = combineSummary(retVal, getBasicSummary());
		retVal = combineSummary(retVal, getPOGInfoQuerySummary());
		retVal = combineSummary(retVal, getSpeciesQuerySummary());
		retVal = combineSummary(retVal, getDEQuerySummary());
		
		if(retVal.length() == 0) return "Show All";
		return retVal;
	}
	
	private String getSpeciesQuery() {
		String retVal = "";
		if(theAssemCountPanel.getIncludedNames() != null) {
			String [] labels = theAssemCountPanel.getIncludedNames();
			String boolLabel = theAssemCountPanel.getIncAnd()?"AND":"OR";
			int range = theAssemCountPanel.getIncludeLimit();
			
			String query = "(pog_groups.A__" + labels[0] + " >= " + range;
			for(int x=1; x<labels.length; x++) {
				query += " " + boolLabel + " pog_groups.A__" + labels[x] + " >= " + range;
			}
			query += ")";
			retVal = combineBool(retVal, query, true);
		}
		if(theAssemCountPanel.getExcludedNames() != null) {
			String [] labels = theAssemCountPanel.getExcludedNames();
			String boolLabel = theAssemCountPanel.getExAnd()?"AND":"OR";
			int range = theAssemCountPanel.getExcludeLimit();
			
			String query = "(pog_groups.A__" + labels[0] + " <= " + range;
			for(int x=1; x<labels.length; x++) {
				query += " " + boolLabel + " pog_groups.A__" + labels[x] + " <= " + range;
			}
			query += ")";
			retVal = combineBool(retVal, query, true);
		}
		return retVal;
	}

	private String getSpeciesQuerySummary() {
		String retVal = "";
		if(theAssemCountPanel.getIncludedNames() != null) {
			String [] labels = theAssemCountPanel.getIncludedNames();
			String boolLabel = theAssemCountPanel.getIncAnd()?"AND":"OR";
			int range = theAssemCountPanel.getIncludeLimit();
			
			String query = "(" + labels[0] + " >= " + range;
			for(int x=1; x<labels.length; x++) {
				query += " " + boolLabel + " " + labels[x] + " >= " + range;
			}
			query += ")";
			retVal = combineSummary(retVal, query);
		}
		if(theAssemCountPanel.getExcludedNames() != null) {
			String [] labels = theAssemCountPanel.getExcludedNames();
			String boolLabel = theAssemCountPanel.getExAnd()?"AND":"OR";
			int range = theAssemCountPanel.getExcludeLimit();
			
			String query = "(" + labels[0] + " <= " + range;
			for(int x=1; x<labels.length; x++) {
				query += " " + boolLabel + " " + labels[x] + " <= " + range;
			}
			query += ")";
			retVal = combineSummary(retVal, query);
		}
		return retVal;
	}

	private String getDEQuery() {
		return theDEPanel.getSQLClusterIDs(getMethod());
	}

	private String getDEQuerySummary() {
		return theDEPanel.getSummary();
	}

	private String getBasicQuery() {
		String retVal = "";
		String searchStr = txtPOGID.getText().trim();
		if(txtPOGID.isEnabled() && searchStr.length() > 0)
			retVal = combineBool(retVal, "pog_groups.PGstr LIKE '%" + searchStr + "%'", true);
		searchStr = txtBestHitID.getText().trim();
		if(txtBestHitID.isEnabled() && searchStr.length() > 0)
			retVal = combineBool(retVal, "POGHITS.HITstr LIKE '%" + searchStr + "%'", true);
		searchStr = txtBestHitDescrip.getText().trim();
		if(txtBestHitDescrip.isEnabled() && searchStr.length() > 0)
			retVal = combineBool(retVal, "POGHITS.description LIKE '%" + searchStr + "%'", true);
		
		return retVal;
	}
	private String getBasicSummary() {
		String retVal = "";
		String searchStr = txtPOGID.getText().trim();
		if(txtPOGID.isEnabled() && searchStr.length() > 0)
			retVal = combineSummary(retVal, "Cluster ID contains '" + searchStr + "'");
		searchStr = txtBestHitID.getText().trim();
		if(txtBestHitID.isEnabled() && searchStr.length() > 0)
			retVal = combineSummary(retVal, "Best hit contains '" + searchStr + "'");
		searchStr = txtBestHitDescrip.getText().trim();
		if(txtBestHitDescrip.isEnabled() && searchStr.length() > 0)
			retVal = combineSummary(retVal, "Best hit description contains '" + searchStr + "'");
		return retVal;
	}
	public int getMethod() {
		if(btnCmbMethod.getSelectedIndex() > 0) 
			return theParentFrame.getMethodIDForName(btnCmbMethod.getSelectedItem());
		else return -1;
	}
	private String getPOGInfoQuery() {
		String retVal = "";
		if(btnCmbMethod.getSelectedIndex() > 0) 
			retVal = combineBool(retVal, "pog_groups.PMid = " + theParentFrame.getMethodIDForName(btnCmbMethod.getSelectedItem()), true);
		if(cmbTaxa.isEnabled() && cmbTaxa.getSelectedIndex() > 0)
			retVal = combineBool(retVal, "pog_groups.taxa = '" + cmbTaxa.getSelectedItem() + "'", true);
		return retVal;
	}
	private String getPOGInfoQuerySummary() {
		String retVal = "";
		if(btnCmbMethod.getSelectedIndex() > 0) 
			retVal = combineSummary(retVal, "Method '" + btnCmbMethod.getSelectedItem() + "'");
		if(cmbTaxa.isEnabled() && cmbTaxa.getSelectedIndex() > 0)
			retVal = combineSummary(retVal, "Taxa = " + cmbTaxa.getSelectedItem());
		return retVal;
	}
	
	/*************************************************************
	 * CreateMainPanel
	 */
	private void createMainPanel() {
		mainPanel = new JPanel();

		createButtonPanel();
		//createShowButtonPanel();
		createSections();
	}
	
	private void createButtonPanel() {
		buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
		buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		buttonPanel.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		
		btnSearch = new JButton("View Filtered Clusters");
		btnSearch.setBackground(Globals.FUNCTIONCOLOR);
		btnSearch.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ListDataPanel newPanel = new ListDataPanel(theParentFrame, "Filter " + theParentFrame.getNextLabelNum("Filter ") + ": ", ListDataPanel.MODE_POG);
				theParentFrame.addResultPanel(newPanel, newPanel.getName(), newPanel.getSummary());
			}
		});
		
		btnClear = new JButton("Clear");
		btnClear.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		btnClear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clearFilters();
			}
		});	
		
		btnHelp = new JButton("Help");
		btnHelp.setBackground(Globals.HELPCOLOR);
		btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				UserPrompt.displayHTMLResourceHelp(theParentFrame, "Cluster Filter Help", "html/viewMultiTCW/POGQueryPanel.html");
			}
		});
		
		buttonPanel.add(btnSearch);
		buttonPanel.add(Box.createHorizontalStrut(5));
		buttonPanel.add(btnClear);
		buttonPanel.add(Box.createHorizontalStrut(5));
		buttonPanel.add(btnHelp);
		buttonPanel.setMaximumSize(buttonPanel.getPreferredSize());
	}
	
	//Left out for now since we don't need expand/collapse all
	private void createShowButtonPanel() {
		showButtonPanel = new JPanel();
		showButtonPanel.setLayout(new BoxLayout(showButtonPanel, BoxLayout.LINE_AXIS));
		showButtonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		showButtonPanel.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		
		btnExpand = new JButton("Expand All");
		btnExpand.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		btnExpand.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				for(int x=0; x<theSections.length; x++)
					theSections[x].expand();
			}
		});
		
		btnCollapse = new JButton("Collapse All");
		btnCollapse.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		btnCollapse.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				for(int x=0; x<theSections.length; x++)
					theSections[x].collapse();
			}
		});

		showButtonPanel.add(btnExpand);
		showButtonPanel.add(Box.createHorizontalStrut(10));
		showButtonPanel.add(btnCollapse);
		
		showButtonPanel.setMaximumSize(showButtonPanel.getPreferredSize());
	}
	
	private void createSections() {
		theSections = new CollapsiblePanel[SECTIONS.length];
		
		for(int x=0; x<theSections.length; x++) {
			theSections[x] = new CollapsiblePanel(SECTIONS[x], SECTIONS_DESC[x]);
			theSections[x].setAlignmentX(Component.LEFT_ALIGNMENT);
		}
		theSections[0].add(createBasicPanel());
		theSections[1].add(createPOGInfoPanel());
		theSections[2].add(createSpeciesPanel());
		theSections[3].add(createDEPanel()); 
	}
	
	private JPanel createSpeciesPanel() {
		JPanel retVal = new JPanel();
		retVal.setAlignmentX(Component.LEFT_ALIGNMENT);
		retVal.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		retVal.setLayout(new BoxLayout(retVal, BoxLayout.PAGE_AXIS));
		
		theAssemCountPanel = new AssemblyCountPanel(theParentFrame); 
		retVal.add(theAssemCountPanel);
		return retVal;
	}
	
	private JPanel createDEPanel() {
		JPanel retVal = new JPanel();
		retVal.setAlignmentX(Component.LEFT_ALIGNMENT);
		retVal.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		retVal.setLayout(new BoxLayout(retVal, BoxLayout.PAGE_AXIS));
		
		theDEPanel = new POGQueryDE(theParentFrame, theParentFrame.hasNegDE()); 
		retVal.add(theDEPanel);
		return retVal;
	}
	private JPanel createBasicPanel() {
		JPanel retVal = new JPanel();
		retVal.setAlignmentX(Component.LEFT_ALIGNMENT);
		retVal.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		retVal.setLayout(new BoxLayout(retVal, BoxLayout.PAGE_AXIS));
		
		JPanel tempRow = getNewRowPanel();	
		tempRow.add(new JLabel("Substring"));
		tempRow.add(Box.createHorizontalStrut(5));
		txtPOGID = new JTextField(20);
		txtPOGID.setMaximumSize(txtPOGID.getPreferredSize());
		txtPOGID.setMinimumSize(txtPOGID.getPreferredSize());
		tempRow.add(txtPOGID);
		tempRow.add(Box.createHorizontalStrut(5));
		lblPOGID = new JLabel("in Cluster ID");
		tempRow.add(lblPOGID);		
		retVal.add(tempRow);
		retVal.add(Box.createVerticalStrut(5));
		
		tempRow = new JPanel();
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.add(new JLabel("Substring"));
		tempRow.add(Box.createHorizontalStrut(5));
		txtBestHitID = new JTextField(20);
		txtBestHitID.setMaximumSize(txtBestHitID.getPreferredSize());
		txtBestHitID.setMinimumSize(txtBestHitID.getPreferredSize());
		tempRow.add(txtBestHitID);
		tempRow.add(Box.createHorizontalStrut(5));
		lblBestHitID = new JLabel("in Cluster Best Hit ID");
		tempRow.add(lblBestHitID);	
		retVal.add(tempRow);
		retVal.add(Box.createVerticalStrut(5));

		tempRow  = getNewRowPanel();
		tempRow.add(new JLabel("Substring"));
		tempRow.add(Box.createHorizontalStrut(5));
		txtBestHitDescrip = new JTextField(20);
		txtBestHitDescrip.setMaximumSize(txtBestHitDescrip.getPreferredSize());
		txtBestHitDescrip.setMinimumSize(txtBestHitDescrip.getPreferredSize());
		tempRow.add(txtBestHitDescrip);
		tempRow.add(Box.createHorizontalStrut(5));
		lblBestHitDescrip = new JLabel("in Cluster Best Hit Description");
		tempRow.add(lblBestHitDescrip);
		retVal.add(tempRow);	
		retVal.add(Box.createVerticalStrut(10));
		
		return retVal;
	}
	
	private JPanel createPOGInfoPanel() {
		JPanel retVal = new JPanel();
		retVal.setAlignmentX(Component.LEFT_ALIGNMENT);
		retVal.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		retVal.setLayout(new BoxLayout(retVal, BoxLayout.PAGE_AXIS));
		
		// All taxa
		JPanel tempRow = getNewRowPanel();		
		tempRow.add(new JLabel("Taxa type"));
		retVal.add(tempRow);
		retVal.add(Box.createVerticalStrut(5));

		cmbTaxa = new ButtonComboBox();
		cmbTaxa.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		cmbTaxa.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		cmbTaxa.addItem("Any");
		String [] taxa = theParentFrame.getTaxaList();
		for(int x=0; x<taxa.length; x++) {
			cmbTaxa.addItem(taxa[x]);
		}
		cmbTaxa.setSelectedIndex(0);
		cmbTaxa.setMaximumSize(cmbTaxa.getPreferredSize());
		cmbTaxa.setMinimumSize(cmbTaxa.getPreferredSize());
		
		tempRow = getNewRowPanel();
		tempRow.add(cmbTaxa);
		retVal.add(tempRow);
				
		retVal.add(Box.createVerticalStrut(10));
		
		// All methods
		retVal.add(new JLabel("Cluster generation method"));
		retVal.add(Box.createVerticalStrut(5));
		
		btnCmbMethod = new ButtonComboBox();
		btnCmbMethod.addItem("All methods");
		
		String [] methodNames = theParentFrame.getMethodNames();
		
		if(methodNames != null) {
			for(int x=0; x<methodNames.length; x++)
				btnCmbMethod.addItem(methodNames[x]);
		}

		btnCmbMethod.setMaximumSize(btnCmbMethod.getPreferredSize());
		btnCmbMethod.setMinimumSize(btnCmbMethod.getPreferredSize());
		btnCmbMethod.setSelectedIndex(0);
		
		tempRow = getNewRowPanel();
		tempRow.add(btnCmbMethod);
		retVal.add(tempRow);
				
		return retVal;
	}
	
	private JPanel getNewRowPanel() {
		JPanel tempRow = new JPanel();
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		return tempRow;
	}
	
	private void buildPanel(boolean expandAll) {
		removeAll();
		setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
		setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		mainPanel.removeAll();
		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
		mainPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		mainPanel.setBackground(theParentFrame.getSettings().getFrameSettings().getBGColor());
		
		add(buttonPanel);
		add(Box.createVerticalStrut(5));
		if(showButtonPanel != null) {
			add(showButtonPanel);
			add(Box.createVerticalStrut(10));
		}		

		for(int x=0; x<theSections.length; x++) {
			if(expandAll)
				theSections[x].expand();
			mainPanel.add(theSections[x]);
		}

		JScrollPane sPane = new JScrollPane(mainPanel);
		add(sPane);
}
	
	//This is repeated in every query panel.. necessary evil for now
	private static String combineBool(String left, String right, boolean isAND) {
		if(left == null || left.length() == 0)
			return right;
		if(right == null || right.length() == 0)
			return left;
		if(isAND)
			return left + " AND " + right;
		return left + " OR " + right;
	}
	
	private static String combineSummary(String left, String right) {
		if(left == null || left.length() == 0)
			return right;
		if(right == null || right.length() == 0)
			return left;
		return left + ", " + right;
	}
	
	private ViewerFrame theParentFrame = null;
	
	//Top button panel
	private JPanel buttonPanel = null;
	private JButton btnSearch = null;
	private JButton btnClear = null;
	private JButton btnHelp = null;
	
	//Main panel
	private JPanel mainPanel = null;
	private JPanel showButtonPanel = null;
	//Left out for now since we don't need expand/collapse all
	private JButton btnExpand = null, btnCollapse = null;
	private CollapsiblePanel [] theSections = null;
	
	//Species
	private AssemblyCountPanel theAssemCountPanel = null;
	//POG Library counts
	private POGQueryDE theDEPanel = null;
	//POD ID
	private JTextField txtPOGID = null;
	private JLabel lblPOGID = null;
	//Best Hit
	private JTextField txtBestHitID = null;
	private JLabel lblBestHitID = null;
	private JTextField txtBestHitDescrip = null;
	private JLabel lblBestHitDescrip = null;
	
	//Methods
	private ButtonComboBox btnCmbMethod = null;
	
	//Pog groups
	private  ButtonComboBox cmbTaxa = null;
}
